#ifndef __TFTP_SERVER_HPP__
#define __TFTP_SERVER_HPP__

#include <netinet/in.h>
#include <arpa/inet.h>
#include <tftp.h>
#include <thread>
#include <chrono>
#include <mutex>

class tftp_agent
{
public:
     tftp_agent(const tftp_request_packet_s req,const int sock,struct sockaddr_in clt);
    ~tftp_agent();

private:
    tftp_data_packet_s  datapkt;
    tftp_ack_packet_s   ackpkt;
    tftp_error_packet_s errpkt;
    tftp_req_ack_s      reqack;
    struct sockaddr_in  client; /**<  客户端的地址信息 */
    struct sockaddr     toclt;  /**<  发送给客户端的结构信息 */ 
    uint32_t            cltlen;

private:
    std::thread *thd = nullptr;
    void tftp_svr_read_loop(void);
    void tftp_svr_write_loop(void);
    static void tftp_demon_loop(void);

private:
    bool data_ack(uint16_t cmd,uint16_t block); /**<  发送数据回应包 */
    bool file_ack(void);
    bool error_ack(char *msg);
    bool error_ack(uint16_t err,char *msg);
    bool error_ack(int sock,char *msg);
    bool data_send(uint16_t block,tftp_data_packet_s &pkt,uint32_t bytes);
    bool data_recv(uint32_t &cnt);
    bool  ack_recv(void);

private:
    int sock = -1; /**<  通过socket打开的句柄 */
    int fd   = -1; /**<  访问(读或者写)的文件句柄 */
    int16_t  port   = 0; /**<  本tftp线程所占用的服务端口 */
    uint32_t tsize  = 0; /**<  传输的文件长度 */
    uint32_t offset = 0; /**<  传输完成的偏移量 */
    bool running    = false;
    uint32_t stamp  = 0; /**<  时间标识 */
};

#define TFTP_SERVER_PORT (6000)  /**<  tftp服务器的监听端口 */
#define TFTP_AGENT_START (6410)  /**<  tftp多线程代理的起始端口,注意避开TFTP_SERVER_PORT */
#define TFTP_AGENT_NUM   (50)    /**<  tftp多线程代理的数量,注意避开TFTP_SERVER_PORT */

/**<
 使用环境变量tftpserver_log_enable可以打开内置的打印信息
 export tftpserver_log_enable=yes 打开信息
 export tftpserver_log_enable=no  关闭信息
*/


#endif